package com.yhcui.monitor.task;

import com.yhcui.monitor.bean.AppInfo;
import com.yhcui.monitor.bean.MonitorMsg;
import com.yhcui.monitor.sender.Sender;
import com.yhcui.monitor.startup.SpringContextHolder;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

@Slf4j
public class SendMsgTask implements Runnable {

    private Sender sender = SpringContextHolder.getBean("dingDingSender");

    // 队列
    private BlockingQueue<AppInfo> sendMsgQueue;

    private static final String TEMPLATE_APP_FAIL = "%s服务不可访问,负责人:%s,服务地址:%s:%s,@%s";

    private static final String TEMPLATE_APP_FAIL_OUT_LIMIT = "%s服务失败超次数，暂停一段时间发送该服务相关告警信息。负责人:%s,服务地址:,服务端口:%s";

    private static final String  ADMIN_MOBILE = "13260487433";

    private volatile boolean notSendOverTimeMsg = true;

    private static final Cache<String, Integer> cache = Caffeine.newBuilder()
            .expireAfterWrite(30, TimeUnit.MINUTES)
            .maximumSize(100)
            .build();
    public SendMsgTask(BlockingQueue<AppInfo> sendMsgQueue) {
        this.sendMsgQueue = sendMsgQueue;
    }



    @Override
    public void run() {
        while (true) {
            try {
                AppInfo appInfo = sendMsgQueue.take();
                log.info("获取报警队列，准备报警:{}", appInfo);
                String msg;

                if (notOverSendTimes(appInfo)) {

                    msg = String.format(TEMPLATE_APP_FAIL, appInfo.getAppName(), appInfo.getLeader(), appInfo.getDomain(), appInfo.getPort(), appInfo.getMobile());
                    MonitorMsg monitorMsg = MonitorMsg.builder().mobiles(Lists.newArrayList(appInfo.getMobile())).atAll(false).msg(msg).build();
                    sender.sendMsg(monitorMsg);
                    addSendTimes(appInfo);
                    notSendOverTimeMsg = true;
                    continue;
                }
                if (notSendOverTimeMsg) {
                    msg = String.format(TEMPLATE_APP_FAIL_OUT_LIMIT, appInfo.getAppName(), appInfo.getLeader(), appInfo.getDomain(), appInfo.getPort());
                    MonitorMsg  monitorMsg = MonitorMsg.builder().mobiles(Lists.newArrayList(ADMIN_MOBILE)).atAll(false).msg(msg).build();
                    sender.sendMsg(monitorMsg);
                    notSendOverTimeMsg = false;
                } else {
                    log.info("SendMsgTask app:{} 告警超次数，停目发送", appInfo.getAppName());
                }


            } catch (Exception e) {
                log.error("SendMsgTask error", e);
            }

        }
    }

    /**
     * 非线程安全
     * TODO
     * @param appInfo
     */
    public void addSendTimes(AppInfo appInfo) {
        String key = appInfo.getAppName() + ":" + appInfo.getDomain() + ":" + appInfo.getPort();
        int times  = cache.get(key, k -> 0 );
        times ++;
        cache.put(key, times);
    }


    public boolean notOverSendTimes(AppInfo appInfo) {
        String key = appInfo.getAppName() + ":" + appInfo.getDomain() + ":" + appInfo.getPort();
        int times  = cache.get(key, k -> 0 );
        if (times > 2 ) {
            return false;
        }
        return true;
    }

}
